package edu.hawaii.myisern.action;

import java.io.IOException;
import java.math.BigInteger;
import javax.xml.bind.JAXBException;
import edu.hawaii.myisern.collaborations.jaxb.CollaboratingOrganizations;
import edu.hawaii.myisern.collaborations.jaxb.Collaboration;
import edu.hawaii.myisern.collaborations.jaxb.CollaborationTypes;
import edu.hawaii.myisern.collaborations.jaxb.OutcomeTypes;
import edu.hawaii.myisern.collaborations.jaxb.Years;
import edu.hawaii.myisern.model.MyIsernModel;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationError;

/**
 * Handles the Adding of a new collaboration
 * 
 * @author Sonwright M. Gomez
 * 
 */
public class AddCollaborationActionBean extends MyIsernActionBean {

  /** The singleton MyIsernModel. */
  private MyIsernModel myIsern = MyIsernModel.getInstance();

  /** The Collaboration name,which is required. */
  @Validate(required = true)
  private String collaborationName;
  private String collaborationOrgs;
  private String collaborationTypes;
  private String collaborationYears;
  private String collaborationOutcomes;
  private String collaborationDescription;
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";

  /**
   * Returns the error message, which may be empty.
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Set's the error message for the user.
   * 
   * @param errorMessage The error message. 
   */
  public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
  }

  /**
   * Set's the collaboration name.
   * 
   * @param cName the name of the collaboration.
   */
  public void setCollaborationName(String cName) {
    this.collaborationName = cName;
  }

  /**
   * Get's the collab name.
   * 
   * @return collaborationName The collab name.
   */
  public String getCollaborationName() {
    return collaborationName;
  }

  /**
   * Set's the list of collaborating organizations.
   * 
   * @param cOrgs the string of collaborating orgs.
   */
  public void setCollaborationOrgs(String cOrgs) {
    this.collaborationOrgs = cOrgs;
  }

  /**
   * Get's the collab org.
   * 
   * @return collaborationOrgs list of collaborating organizations.
   */
  public String getCollaborationOrgs() {
    return collaborationOrgs;
  }

  /**
   * Set's the list of collaboration types.
   * 
   * @param cTypes the list of collaborating types.
   */
  public void setCollaborationTypes(String cTypes) {
    this.collaborationTypes = cTypes;
  }

  /**
   * Get's the collab types.
   * 
   * @return collaborationTypes list of collaboration types.
   */
  public String getCollaborationTypes() {
    return collaborationTypes;
  }

  /**
   * Set's the list of collaborating years
   * 
   * @param cYears the list of years of collaboration
   */
  public void setCollaborationYears(String cYears) {
    this.collaborationYears = cYears;
  }

  /**
   * Get's the collab collaboration years
   * 
   * @return collaborationYears lists the years of collaborations.
   */
  public String getCollaborationYears() {
    return collaborationYears;
  }

  /**
   * Set's the list of collaboration outcomes
   * 
   * @param cOutcomes the outcomes of the collaborations
   */
  public void setCollaborationOutcomes(String cOutcomes) {
    this.collaborationOutcomes = cOutcomes;
  }

  /**
   * Get's the collab outcomes
   * 
   * @return collaborationOutcomes the outcomes of the collaborations.
   */
  public String getCollaborationOutcomes() {
    return collaborationOutcomes;
  }

  /**
   * Set's the collaboration descriptoin
   * 
   * @param cDescription which is the collab's description.
   */
  public void setCollaborationDescription(String cDescription) {
    this.collaborationDescription = cDescription;
  }

  /**
   * Get's the collab description.
   * 
   * @return collaborationDescriptoin Description of the collaboration
   */
  public String getCollaborationDescription() {
    return collaborationDescription;
  }

  /**
   * A handler that performs the action when the 'login' button is pressed.
   * 
   * @return A Resolution indicating to display the mainMenu.jsp page.
   * @throws IOException If IO error occurs
   * @throws JAXBException if JAXB error occurs
   */
  @DefaultHandler
  public Resolution submitAndSave() throws JAXBException, IOException {
    boolean yearsAreValid = false;
    String delim = "," + "\\s";
    if (getCollaborationName().isEmpty()) {
      ValidationError error = new SimpleError("Requires a Collaboration Name");
      getContext().getValidationErrors().add("collaborationName", error);
      return getContext().getSourcePageResolution();
    }
    else {

      // make sure it doesn't exist already
      if (myIsern.containsCollaboration(this.collaborationName)) {
        setErrorMessage("There is already a Collaboration with that name found "
            + "in the database.");
        return new ForwardResolution("/addCollaboration.jsp");
      }
      else {
        // Adds new Collaboration name
        Collaboration newC = new Collaboration();
        newC.setName(this.collaborationName);

        // Adds Collaborating Organizations
        CollaboratingOrganizations newOrgs = new CollaboratingOrganizations();
        try {
          String[] tempCollabOrg = this.collaborationOrgs.split(delim);
          for (String curr : tempCollabOrg) {
            newOrgs.getCollaboratingOrganization().add(curr.trim());
          }
        }
        catch (NullPointerException e) {
          newOrgs.getCollaboratingOrganization().add("");

        }
        newC.setCollaboratingOrganizations(newOrgs);

        // Add Collaboration types
        CollaborationTypes newTypes = new CollaborationTypes();
        try {
          String[] tempCollabTypes = this.collaborationTypes.split(delim);
          for (String curr : tempCollabTypes) {
            newTypes.getCollaborationType().add(curr.trim());
          }
        }
        catch (NullPointerException e) {
          newOrgs.getCollaboratingOrganization().add("");
        }
        newC.setCollaborationTypes(newTypes);

        // Add Collaboration years

        Years newYears = new Years();
        try {
          String[] tempYears = this.collaborationYears.split(delim);
          int i = 0;
          for (String curr : tempYears) {
            if (myIsern.yearIsValid(curr.trim())) {
              try {
                BigInteger bigNum = new BigInteger(curr.trim());
                newYears.getYear().add(bigNum);
                i++;
              }
              catch (NumberFormatException e) {
                e.printStackTrace();
              }
            }
          }
          //If no years are valid, will set default year to 1990 to be changed later
          if (i == 0) {
            BigInteger temp = new BigInteger("1990");
            newYears.getYear().add(temp);
          }
        }
        catch (NullPointerException e) {
          BigInteger bigNum = new BigInteger("1990");
          newYears.getYear().add(bigNum);
        }
        newC.setYears(newYears);

        // Add Collaboration outcomes
        OutcomeTypes newOutcomeTypes = new OutcomeTypes();
        try {
          String[] tempOutcomeTypes = this.collaborationOutcomes.split(delim);
          for (String curr : tempOutcomeTypes) {
            newOutcomeTypes.getOutcomeType().add(curr.trim());
          }
        }
        catch (NullPointerException e) {
          newOutcomeTypes.getOutcomeType().add("");
        }
        newC.setOutcomeTypes(newOutcomeTypes);

        // Add collaboration description
        try {
          newC.setDescription(this.collaborationDescription);
        }
        catch (NullPointerException e) {
          newC.setDescription("");
        }
        myIsern.addCollaboration(newC);
        myIsern.saveCollaboration();

        return new ForwardResolution("/mainMenu.jsp");
      }
    }

  }

  /**
   * Goes back to the main menu without saving anything.
   * 
   * @return a resolution to display the main menu.
   */
  @DontValidate
  public Resolution cancel() {
    return new ForwardResolution("/mainMenu.jsp");
  }

}
